package com.senlingspace.system.event;

import com.alibaba.fastjson2.JSON;
import com.senlingspace.system.domain.*;
import com.senlingspace.system.domain.dto.RefundOrderDto;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;

/**
 * 公共监听器
 *
 * @author lebronjames
 * @date 2024/07/18
 */
@AllArgsConstructor
@Slf4j
@Component
public class CommonEventListener {

    private final EventHandlerService eventHandlerService;

    private final Map<Class<?>, Consumer<Object>> eventHandlers = new HashMap<>();

    @PostConstruct
    public void init() {
        // 同步票类至票价方案详情
        eventHandlers.put(SlkjTicketCategory.class, data ->
                eventHandlerService.handleTicketCategory((SlkjTicketCategory) data)
        );

        // 新增票价方案，同步其他未设置的票类信息至票价方案详情
        eventHandlers.put(SlkjFareScheme.class, data ->
                eventHandlerService.handleCreateFareScheme(((SlkjFareScheme) data).getId())
        );

        // 计算订单分账
        eventHandlers.put(SlkjOrder.class, data ->
                eventHandlerService.handleOrder((SlkjOrder) data)
        );

        // 退款 分账回退
        eventHandlers.put(RefundOrderDto.class, data ->
                eventHandlerService.handleRefundOrder((RefundOrderDto) data)
        );
    }

    @Async("threadPoolTaskExecutor")
    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
    public void onEvent(ActionEvent<?> event) {
        log.info("监听到事件，入参信息：{}", JSON.toJSONString(event));

        Consumer<Object> handler = eventHandlers.get(event.getData().getClass());

        if (handler != null) {
            handler.accept(event.getData());
        } else {
            log.warn("未处理的事件类型：{}，数据：{}", event.getData().getClass(), JSON.toJSONString(event.getData()));
        }
    }

}
